﻿#include "ui/canvas.h"
#include "texture.h"
#include "shared.h"
#include "draw.h"

using namespace std;
using namespace anip;
//anip::Shader* anip::ui::Canvas::shader = nullptr;

ui::Canvas::Canvas(Container* parent, invec2 pos, invec2 size) : texture(nullptr)
{
	/*static const char* fragment =
		"uniform sampler2D tex;"
		"uniform vec4 scaleoff;"
		"uniform ivec2 cut_flip;"
		"uniform vec2 size;"
		"in vec2 pos;"
		"void main()"
		"{"
			"vec2 pt = pos / size;"
			"if (cut_flip.y == 1)"
				"pt = vec2(pt.x, 1 - pt.y) / scaleoff.xy - scaleoff.zw;"
			"else "
				"pt = pt / scaleoff.xy - scaleoff.zw;"
			"if (cut_flip.x == 1 && (min(pt.x, pt.y) < 0.0 || max(pt.x, pt.y) > 1.0))"
				"gl_FragColor = vec4(0);"
			"else "
				"gl_FragColor = texture2D(tex, pt);"
		"}";

	if (shader == nullptr)
	{
		ShaderPart* frag = new ShaderPart(ShaderPart::Type::Fragment, fragment);
		shader = new Shader{ Internals::standardVertexShader(), frag };
		anip::Shared::add({ shader, frag });
	}*/

	if (parent != nullptr) parent->addChild(*this);
	setPosition(pos);
	setSize(size);
}

void ui::Canvas::fit()
{
	if (texture == nullptr) return;

	float s;
	switch (fitType)
	{
	case FitType::Center:
		scale = { 1, 1 };
		offset = (_size - texture->size()) * 0.5f;
		cutoff = true;
		break;
	case FitType::Rescale:
		s = min(_size.x / texture->width(), _size.y / texture->height());
		scale = { s, s };
		offset = (_size - texture->size() * s) * 0.5f;
		cutoff = true;
		break;
	case FitType::Stretch:
		scale = _size / texture->size();
		offset = { 0, 0 };
		break;
	case FitType::Tile:
		scale = { 1, 1 };
		offset = { 0, 0 };
		cutoff = false;
		break;
	case FitType::Manual:
		break;
	default:
		throw invalid_argument("type");
	}

	postSignal({ ui::Signal::Type::NeedsRedraw });
}

void ui::Canvas::paint()
{
	Draw::rect(_absPos, _size, backColor);
	Context::addScissor(_absPos, _size);

	fit();
	if (texture != nullptr)
		Draw::texture(_absPos + offset, texture->size() * scale, *texture);

	Control::paint();
}

void ui::Canvas::flow(Flow& f)
{
	if (layoutOptions.type != layoutOptions.Flow)
	{
		Control::flow(f);
	}
	else
	{
		defaultFlowLayout(f);
	}
}

void ui::Canvas::processScroll(invec2 pos)
{
	if (onScroll)
		onScroll(*this, pos);
	Control::processScroll(pos);
}